package model.elements.ArtificialIntelligence;

import java.util.Random;

import model.elements.NonPlayerCharacter;
import model.elements.attributes.Coordinate2D;
import model.elements.commands.ElementCommand;
import model.elements.commands.ElementCommandFactory;
import model.elements.states.movement.ElementMovementState;
import model.elements.states.movement.MovingDown;
import model.elements.states.movement.MovingLeft;
import model.elements.states.movement.MovingRight;
import model.elements.states.movement.MovingUp;
import model.exceptions.ModelExceptions;
import model.map.ElementsMap;

// TODO: Auto-generated Javadoc
/**
 * The Class MovesRandomShootsRandom.
 */
public class MovesRandomShootsRandom implements ArtificialIntelligence
{	
	
	/** The m_state. */
	int m_state = 0;
	
	/** The m_used weapon. */
	boolean m_usedWeapon = false;
	
	/** The m_weapon state. */
	int m_weaponState = 0;
	
	/** The m_last direction. */
	ElementMovementState m_lastDirection;
	
	/** The m_coin flipper. */
	Random m_coinFlipper = new Random(); 
	
	/** The total move turns. */
	int totalMoveTurns;		
	
	/** The m_map reference. */
	ElementsMap m_mapReference = null; 
	
	/**
	 * Instantiates a new moves random shoots random.
	 *
	 * @param i the i
	 */
	public MovesRandomShootsRandom(int i) {
		m_lastDirection = getRandomDirection();
		totalMoveTurns = i;
	}
	
	/**
	 * Instantiates a new moves random shoots random.
	 *
	 * @param i the i
	 * @param map the map
	 */
	public MovesRandomShootsRandom(int i, ElementsMap map) {
		m_lastDirection = getRandomDirection();
		totalMoveTurns = i;
		m_mapReference = map;
	}
	
	/**
	 * Sonar.
	 *
	 * @param from the from
	 * @param direction the direction
	 * @param size the size
	 * @return the int
	 */
	private int Sonar(Coordinate2D from, Coordinate2D direction, int size) {
		
		int returnInt = 0;
		boolean Found = false;
		Coordinate2D nextTile;
		
		for(int i = 0; !Found && i<size ;i++) {
			
			nextTile = Coordinate2D.add( 
					from, 
					Coordinate2D.multiply(
							i,
							direction
					));
			Found = m_mapReference.checkIfElementsIn(nextTile);
			if(!Found)returnInt++;
				
		}
		
		return returnInt;
	}
	
	/**
	 * Gets the sonar direction.
	 *
	 * @param nonPlayerCharacter the non player character
	 * @return the sonar direction
	 */
	private ElementMovementState getSonarDirection( NonPlayerCharacter nonPlayerCharacter ) {
		int randomMax 	= 4;
		int rightChance = 0;
		int leftChance 	= rightChance+1;
		int upChance 	= leftChance+1;
		int downChance 	= upChance+1;
		
		if(m_mapReference != null) {
			rightChance = 10*Sonar(	nonPlayerCharacter.getPosition(), 
					new Coordinate2D(1,0), 
					3 );
			randomMax += rightChance;
			
			leftChance = rightChance + 10*Sonar(	nonPlayerCharacter.getPosition(), 
					new Coordinate2D(-1,0), 
					3 );
			randomMax += leftChance;
			
			upChance =  leftChance + 10*Sonar(		nonPlayerCharacter.getPosition(), 
					new Coordinate2D(0,1), 
					3 );
			randomMax += upChance;
			
			downChance = upChance + 10*Sonar(	nonPlayerCharacter.getPosition(), 
					new Coordinate2D(0,-1), 
					3 );
			randomMax += downChance;
		}
		
		int coinFlip = m_coinFlipper.nextInt(randomMax);
		
		if( coinFlip <= rightChance ) {
			System.out.print("Voy a la derecha\n");
			return new MovingRight();			
		}
		
		if( coinFlip <= leftChance ) {
			System.out.print("Voy a la izquierda\n");
			return new MovingLeft();		
		}
		
		if( coinFlip <= upChance ) {
			System.out.print("Voy a la arriba\n");
			return new MovingUp();		
		}
		
		if( coinFlip <= downChance ) {
			System.out.print("Voy a la abajo\n");
			return new MovingDown();			
		}
		
		return m_lastDirection;	
	}
	
	/**
	 * Gets the random direction.
	 *
	 * @return the random direction
	 */
	private ElementMovementState getRandomDirection() {
		
		switch (m_coinFlipper.nextInt(4)) {
			case 0:
				System.out.print("Voy a la derecha\n");
				return new MovingRight();
			case 1:
				System.out.print("Voy a la izquierda\n");
				return new MovingLeft();
			case 2:
				System.out.print("Voy a la arriba\n");
				return new MovingUp();
			case 3:
				System.out.print("Voy a la abajo\n");
				return new MovingDown();
		}
		return m_lastDirection;		
	}
	
	/* (non-Javadoc)
	 * @see model.elements.ArtificialIntelligence.ArtificialIntelligence#getCommand(model.elements.NonPlayerCharacter)
	 */
	@Override
	public ElementCommand getCommand( NonPlayerCharacter nonPlayerCharacter ) throws ModelExceptions {
		
		if ( m_state < totalMoveTurns ) 
			++m_state;
		else {
			if(m_usedWeapon == false)
				if(m_mapReference != null)
					m_lastDirection = getSonarDirection(nonPlayerCharacter);
				else 
					m_lastDirection = getRandomDirection();
			else {
				m_weaponState++;
				if(m_weaponState >= 5) {
					m_weaponState = 0;
					m_usedWeapon = false;
				}
			}
			
			m_state = 0;
			
			if( nonPlayerCharacter.canUseWeapon() && m_coinFlipper.nextInt(9) == 0 ) {
				System.out.print("Uso mi arma\n");
				m_usedWeapon = true;
				m_weaponState = 0;
				return ElementCommandFactory.getElementUseWeapon();
			}
		}
		
		return ElementCommandFactory.getElementMove( m_lastDirection );
		
	}
	
}
